﻿//----------------------------------------------------------------------------------------------------
// The GameManager is the base class for all managers
//----------------------------------------------------------------------------------------------------
package HG.Managers
{
	import HG.GameService;
	
	import HG.Events.PlayerEvent;
	import HG.Events.TurnEvent;
	import HG.Events.NodeEvent;
	
	import HG.GameDataTypes.Player;
	
	import HG.AI.*;
	
	public class AIManager extends IGameManager
	{
		var m_playerManager:PlayerManager;
		var m_turnManager:TurnManager;
		var m_gameRuleManager:GameRuleManager;
		var m_levelManager:LevelManager;
		
		var m_AIs:Array;
		var m_PlayerIDtoAI:Array;
		
		var m_AIProcessTick:Number;
		
		//----------------------------------------------------------------------------------------------------
		public override function AIManager()
		{
			m_AIs = new Array();
			m_PlayerIDtoAI = new Array();
			
			m_AIProcessTick = -1;
		}
		
		//----------------------------------------------------------------------------------------------------
		public override function Initialize()
		{
			m_playerManager = GameService.GetInstance().GetPlayerManager();
			m_playerManager.addEventListener(PlayerEvent.JOIN, OnPlayerJoin);
			m_playerManager.addEventListener(PlayerEvent.FATE, OnPlayerFate);
			
			m_turnManager = GameService.GetInstance().GetTurnManager();
			m_turnManager.addEventListener(TurnEvent.BEGIN, OnTurnStart);
			
			m_levelManager = GameService.GetInstance().GetLevelManager();
			m_levelManager.addEventListener(NodeEvent.CAPTURE, OnNodeCaptured);
			
			m_AIProcessTick = -1;
		}
		
		//----------------------------------------------------------------------------------------------------
		public override function Shutdown()
		{
			
		}
		
		//----------------------------------------------------------------------------------------------------
		public override function OnTick(DeltaTime:Number)
		{
			if (m_AIProcessTick != -1)
			{
				var AIID:Number = m_AIProcessTick;
				m_AIProcessTick = -1;
				
				m_PlayerIDtoAI[AIID].PerformActions();
				m_turnManager.PlayerInputComplete(AIID);
			}
		}
		
		//----------------------------------------------------------------------------------------------------
		private function OnPlayerJoin(evt:PlayerEvent)
		{
			var newPlayer:Player = m_playerManager.GetPlayer(evt.m_playerNumber);
			
			if (newPlayer.GetType() == PlayerManager.PLAYER_COMPUTER)
			{
				var newAI:IAIPlayer = new SentryPlayer(evt.m_playerNumber);
				
				m_AIs.push(newAI);
				m_PlayerIDtoAI[evt.m_playerNumber] = newAI;
				
				m_PlayerIDtoAI[evt.m_playerNumber].SetActive(true);
			}
		}
		
		//----------------------------------------------------------------------------------------------------
		private function OnPlayerFate(evt:PlayerEvent)
		{
			if (evt.m_fate != GameRuleManager.FATE_DEFEAT)
				return;
			
			if (m_PlayerIDtoAI[evt.m_playerNumber])
			{
				m_PlayerIDtoAI[evt.m_playerNumber].SetActive(false);
			}
		}
		
		//----------------------------------------------------------------------------------------------------
		private function OnNodeCaptured(evt:NodeEvent)
		{
			// dont let AI's trip on sentry kills.
			if (evt.m_node.GetType() == NodeManager.NODE_SENTRY ||
				evt.m_node.GetType() == NodeManager.NODE_ROOT)
				return;
				
			// dont let AI's trip other AI's, thats just not fair.
			if (m_playerManager.GetPlayer(evt.m_capBy).GetType() == PlayerManager.PLAYER_COMPUTER)
				return;
			
			var tripChances:Array = evt.m_node.GetTripChances();
			
			var index:Number = 0;
			var listLength:Number = m_AIs.length;
			
			for (index = 0; index < listLength; ++index)
			{
				var AIID:Number = m_AIs[index].GetPlayerID();
				var AIPlayer:Player = m_playerManager.GetPlayer(AIID);
				var AIRootNode:Number = AIPlayer.GetRootNode();
				
				if (tripChances[AIRootNode])
				{
					var tripChance = tripChances[AIRootNode];
					var tripNumber = Math.random();
					
					if (tripNumber < tripChance)
					{
						// Ive been tripped!
						m_AIs[index].TripSentry(evt.m_node.GetID(), evt.m_capBy);
					}
				}
			}
		}
		
		//----------------------------------------------------------------------------------------------------
		private function OnTurnStart(evt:TurnEvent)
		{
			if (m_PlayerIDtoAI[evt.m_inputPlayerID])
			{
				// Set this AI to process on next tick. (dont process it during this event)
				m_AIProcessTick = evt.m_inputPlayerID;
			}
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetTurnsToReachPlayer():Number
		{
			var lowestNumber:Number = 99;
			
			var index:Number = 0;
			var listLength:Number = m_AIs.length;
			
			for (index = 0; index < listLength; ++index)
			{
				var val:Number = m_AIs[index].GetTurnsToReachPlayer();
				
				if (val <= 0)
					continue;
					
				if (val < lowestNumber)
					lowestNumber = val;
			}
			
			if (lowestNumber != 99)
				return lowestNumber;
				
			return 0;
		}
		
		//----------------------------------------------------------------------------------------------------
	}
}




